<?php

namespace App\Service\College;

use App\Enums\Check\CheckEnum;
use App\Http\Middleware\OpenShop\UserPermissionAuth;
use App\Jobs\Message\FsMessageJob;
use App\Library\Rms\RmsShopApi;
use App\Library\Rms\RmsUserApi;
use App\Models\Appraise\AppraiseModel;
use App\Models\BaseModel;
use App\Models\College\CollegeTrainingOrderLogModel;
use App\Models\College\CollegeTrainingOrderModel;
use App\Models\College\CollegeTrainingOrderPlanUserModel;
use App\Models\College\CollegeTrainingOrderUserModel;
use App\Models\College\CollegeTrainingPlanModel;
use App\Models\Common\ConfigModel;
use App\Models\Common\ResourcesModel;
use App\Models\Kms\User\KmsUser;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Service\BaseService;
use App\Service\Check\CheckStreamParam;
use App\Service\OpenShop\Feishu\ShopTagsService;
use App\Service\OpenShop\User\RmsUserService;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Kuafu\File\FileUtil;

class CollegeTrainOrderService extends BaseService
{
    /**
     * 获得培训订单  商家端与web端通用
     * @param int $pageSize
     * @param int $pageNum
     * @param int $shopId 根据shopId判断
     * @return array
     * @throws GuzzleException
     */
    public static function getTrainOrderList(int $pageSize, int $pageNum, $orderNo, $planName, $shopIds, $trainType, $startTime, $endTime, $status, int $shopId = 0, string $teacherShopIds = "", bool $export = false, int $campus = 0, string $startOpenTime = '', string $endOpenTime = ''): array
    {
        $paginator = CollegeTrainingOrderModel::query()
            ->when($shopId, function ($query) use ($shopId) {
                $query->where('studentShopId', $shopId);
            })
            ->when(mb_strlen($orderNo), function ($query) use ($orderNo) {
                $query->where('orderNo', $orderNo);
            })
            ->when(mb_strlen($planName), function ($query) use ($planName) {
                $child = CollegeTrainingPlanModel::query()
                    ->where('name', 'like', "%{$planName}%")
                    ->select('id');
                $query->whereRaw("planId in (" . BaseModel::toSqlWithParam($child) . ')');
            })
            ->when(mb_strlen($shopIds), function ($query) use ($shopIds) {
                $shopArr = explode(',', $shopIds);
                $query->whereIn('studentShopId', $shopArr);
            })
            ->when($trainType, function ($query) use ($trainType) {
                $child = CollegeTrainingPlanModel::query()
                    ->where('type', $trainType)
                    ->select('id');
                $query->whereRaw("planId in (" . BaseModel::toSqlWithParam($child) . ')');
            })
            ->when($campus, function ($query) use ($campus) {
                $child = CollegeTrainingPlanModel::query()
                                                 ->where('campus', $campus)
                                                 ->select('id');
                $query->whereRaw("planId in (" . BaseModel::toSqlWithParam($child) . ')');
            })
            ->when(mb_strlen($startTime), function ($query) use ($startTime, $endTime) {
                $query->where('createdAt', '>=', strtotime($startTime))->where('createdAt', '<=', strtotime($endTime));
            })
            ->when(mb_strlen($startOpenTime), function ($query) use ($startOpenTime, $endOpenTime) {
                $shopIds = OpenShopSiteLocationModel::query()->with('mainProcessRel')->where('openTime', '>=', strtotime($startOpenTime))->where('openTime', '<=', strtotime($endOpenTime))->select('orderNo')->get()->map(function ($item) {
                    if (!$item->mainProcessRel) {
                        return null;
                    }

                    return $item->mainProcessRel->shopId;
                })->filter()->values()->toArray();

                $query->whereIn('studentShopId', $shopIds);
            })
            ->when($status, function ($query) use ($status) {
                $query->where('status', $status);
            })
            ->when($teacherShopIds, function ($query) use ($teacherShopIds) {
                $shopArr = explode(',', $teacherShopIds);
                $query->whereIn('teacherShopId', $shopArr);
            })
            ->with(['planRel', 'userIdentityRel', 'userBaseInfoRel', 'resourceTrainCompleteImgRel', 'userRel', 'siteLocationRel'])
            ->orderByDesc('id')
            ->paginate($pageSize, ['*'], 'pageNum', $pageNum);

        $shopIds = $paginator->pluck('studentShopId')->toArray();
        $shopIds = array_merge($shopIds, $paginator->pluck('teacherShopId')->toArray());

        //获得门店信息
        $shopData = (new RmsShopApi())->getShopByIds($shopIds)['data']['shopList'] ?? [];
        $shopList = array_column($shopData, null, 'id');

        // 最大的实操人员数量
        $maxUserCount = 0;
        //查询是否评价过
        $orderNos = $paginator->pluck('orderNo')->toArray();
        $appraiseModel = AppraiseModel::getInfoByWorkOrderNos($orderNos, AppraiseModel::TYPE_OPENSHOP_COLLEGE);//商学院培训单关联评价反馈详情
        $appraiseModel = array_column($appraiseModel, 'id', 'workOrderNo');

        $list = $paginator->map(function (CollegeTrainingOrderModel $collegeTrainingOrderModel) use ($shopList, $export, &$maxUserCount,$appraiseModel) {

            $certificateImg = '';  //结业证书
            $failLetter     = '';  //考试未通过承诺书
            collect($collegeTrainingOrderModel->resourceTrainCompleteImgRel)->each(function (ResourcesModel $resourcesModel) use (&$certificateImg, &$failLetter) {
                if ($resourcesModel->name == 'failLetter') {  //考试未通过承诺书
                    $failLetter = picturePath($resourcesModel->url);
                }
                if ($resourcesModel->name == 'trainCompleteImg') {  //结业证书
                    $certificateImg = picturePath($resourcesModel->url);
                }
            });
            //获取考试状态
            switch ($collegeTrainingOrderModel->status) {
                case CollegeTrainingOrderModel::STATUS_ING:
                    $examStatus = '待考试';
                    break;
                case CollegeTrainingOrderModel::STATUS_WAIT_UPLOAD:
                case CollegeTrainingOrderModel::STATUS_FINISH:
                    $examStatus = '已完成';
                    break;
                case CollegeTrainingOrderModel::STATUS_CLOSE:
                    $examStatus = '-';
                    break;
                default:
                    $examStatus = '待生成';
            }

//            $openTime = (int)optional($collegeTrainingOrderModel->siteLocationRel)->openTime;

            // 没办法了 - 临时方案
            $mainProcessId = (int)OpenShopMainProcessModel::query()->where('shopId', $collegeTrainingOrderModel->studentShopId)->value('id');
            if ($mainProcessId) {
                $openTime = (int)OpenShopSiteLocationModel::query()->where('mainProcessId', $mainProcessId)->where('source', 0)->value('openTime');
            } else {
                $openTime = 0;
            }

            $data = [
                'id'             => $collegeTrainingOrderModel->id,
                'name'           => (string)optional($collegeTrainingOrderModel->planRel)->name,
                'status'         => $collegeTrainingOrderModel->status,
                'statusText'     => CollegeTrainingOrderModel::STATUS_TEXT[$collegeTrainingOrderModel->status] ?? '-',
                'orderNo'        => $collegeTrainingOrderModel->orderNo,
                'userName'       => (string)optional($collegeTrainingOrderModel->userIdentityRel)->name,
                'userMobile'     => (string)optional($collegeTrainingOrderModel->userBaseInfoRel)->mobile,
                'shopCode'       => (string)($shopList[$collegeTrainingOrderModel->studentShopId]['shopCode'] ?? '-'),
                'shopName'       => (string)($shopList[$collegeTrainingOrderModel->studentShopId]['name'] ?? '-'),
                'teacherShopId'  => (int)$collegeTrainingOrderModel->teacherShopId,
                'teacherShopCode' => (string)($shopList[$collegeTrainingOrderModel->teacherShopId]['shopCode'] ?? '-'),
                'teacherShopName' => (string)($shopList[$collegeTrainingOrderModel->teacherShopId]['name'] ?? '-'),
                'trainType'      => CollegeTrainingPlanModel::TYPE_MAPPING[(int)optional($collegeTrainingOrderModel->planRel)->type] ?? '-',
                'actualNum'      => $collegeTrainingOrderModel->actualNum,
                'examStatus'     => $examStatus,
                'planNum'        => $collegeTrainingOrderModel->planNum,
                'createdAt'      => $collegeTrainingOrderModel->createdAt->toDateTimeString(),
                'close' => !in_array($collegeTrainingOrderModel->status, [CollegeTrainingOrderModel::STATUS_FINISH, CollegeTrainingOrderModel::STATUS_CLOSE]),
                    //是否展示关闭
                'upload'         => $collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_WAIT_UPLOAD,      //是否展示实操 / 阅卷
                'isShowLook'     => CollegeTrainingOrderModel::STATUS_FINISH == $collegeTrainingOrderModel->status,           //是否展示查看证书
                'isPass'         => (bool)$certificateImg,                                                                    //是否通过考试
                'certificateImg' => $certificateImg ?: $failLetter,
                'merchantConfirmTime' => $collegeTrainingOrderModel->merchantConfirmTime,
                'result'         => $collegeTrainingOrderModel->result,
                'campusText'     => CollegeTrainingPlanModel::TRAINING_PLANS_CAMPUS_MAPPING[(string)optional($collegeTrainingOrderModel->planRel)->campus] ?? '',
                'finishExamNum'  => $collegeTrainingOrderModel->userRel->whereIn('examResult', [CollegeTrainingOrderUserModel::RESULT_OK, CollegeTrainingOrderUserModel::RESULT_FAIL])->count(),
                'appraiseId'     => (int)($appraiseModel[$collegeTrainingOrderModel->orderNo] ?? 0),
                'openDate'       => $openTime ? date('Y-m-d', $openTime) : '-',
                'shopPattern'    => (int)optional($collegeTrainingOrderModel->siteLocationRel)->shopPattern,
                'shopPatternStr' => OpenShopSiteLocationModel::SHOP_PATTERN_MAPPING[(int)optional($collegeTrainingOrderModel->siteLocationRel)->shopPattern] ?? '-',
                'patternType'    => (string)optional($collegeTrainingOrderModel->siteLocationRel)->patternType,
                'patternTypeStr' => OpenShopSiteLocationModel::getPatternTypeStr((string)optional($collegeTrainingOrderModel->siteLocationRel)->patternType),
            ];

            if ($export) {
                $data['userRel'] = $userRel = $collegeTrainingOrderModel->userRel ?? [];
                if ($maxUserCount < count($userRel)) {
                    $maxUserCount = count($userRel);
                }
            }

            return $data;
        });

        if (!$export) {
            return [
                'list'     => $list,
                'count'    => $paginator->total(),
                'pageSize' => $pageSize,
                'pageNum'  => $pageNum,
            ];
        }

        // 导出
        self::exportLists($list, $maxUserCount);
        return [];
    }

    private static function exportLists(Collection $list, int $maxUserCount)
    {
        ini_set('max_execution_time', 100000);
        header("Content-Disposition: attachment; filename=" . urlencode('培训单') . date('Y-m-d') . '.csv');

        // UTF8的BOM头
        $filename = 'php://output';

        $fd = fopen($filename, 'w+');
        fwrite($fd, "\xEF\xBB\xBF");

        // 表头
        $title = [
            '培训单号',
            '培训计划',
            '培训类型',
            '参训门店',
            '门店模型',
            '售卖品类',
            '带训门店',
            '加盟商',
            '手机号',
            '实际/预计（参训人数）',
            '商家确认时间',
            '下单时间',
            '订单状态',
            '考试状态',
        ];
        for ($i = 1; $i <= $maxUserCount; $i++) {
            $title[] = "学员{$i}姓名";
            $title[] = "学员{$i}理论分数";
            $title[] = "学员{$i}实操分数";
        }

        $userIds = [];
        $list->pluck('userRel.*.userId')->each(function ($item) use(&$userIds) {
            $userIds = array_merge($userIds, $item);
        });
        $userIds = array_values(array_unique($userIds));
        $userInfos = collect((new RmsUserApi())->getUserInfoByIds($userIds, ['id', 'username'])['data'] ?? [])->keyBy('id');

        fputcsv($fd, $title);

        collect($list)->each(function ($item, $k) use (&$fd, $maxUserCount, $userInfos) {
            $content = [
                $item['orderNo'],
                $item['name'] ?: '-',
                $item['trainType'],
                $item['shopCode'].$item['shopName'],
                $item['shopPatternStr'],
                $item['patternTypeStr'],
                $item['teacherShopCode'].$item['teacherShopName'],
                $item['userName'],
                $item['userMobile'],
                '`'.$item['actualNum'].'/'.$item['planNum'],
                $item['merchantConfirmTime'] ? date('Y-m-d H:i:s', $item['merchantConfirmTime']) : '-',
                $item['createdAt'],
                $item['statusText'],
                $item['examStatus'],
            ];

            foreach ($item['userRel'] ?? [] as $val) {
                $content[] = $userInfos[$val['userId'] ?? 0]['username'] ?? '';
                $content[] = $val['examActualScore'] ?? 0;
                $content[] = $val['practiceScore'] ?? 0;
            }

            fputcsv($fd, $content);
            ob_flush();
            flush();
        });


        ob_flush();
        flush();

        if (is_resource($fd)) {
            fclose($fd);
        }

        die;
    }

    /**
     * 获取培训订单详情
     * @param $id
     * @param $userId
     * @return array
     * @throws GuzzleException
     */
    public static function getTrainOrderDetail($id, $userId): array
    {
        $collegeTrainingOrderModel = CollegeTrainingOrderModel::query()
            ->with(['planRel', 'userIdentityRel', 'userBaseInfoRel', 'userRel.resourcePracticeCheckUrlsRel', 'logRel', 'planUserRel', 'resourcePracticeTrainingRel', 'resourceFailLetterRel'])
            ->find($id);

        if (null == $collegeTrainingOrderModel) {
            self::throwErr('详情获取失败');
        }

        if ($collegeTrainingOrderModel->actualNum != $collegeTrainingOrderModel->userRel->count()) {
            $collegeTrainingOrderModel->actualNum = $collegeTrainingOrderModel->userRel->count();
            $collegeTrainingOrderModel->save();
        }

        //获取RMS门店信息
        $shopData = (new RmsShopApi())->getShopByIds([$collegeTrainingOrderModel->studentShopId, $collegeTrainingOrderModel->teacherShopId], ['id', 'shopCode', 'name', 'address', 'lat', 'lng'])['data']['shopList'] ?? [];
        $shopInfo = array_column($shopData, null, 'id');

        //获得该门店所有的用户信息
        $realityStaffIds = $collegeTrainingOrderModel->userRel->pluck('userId')->toArray();
        $expectStaffIds  = $collegeTrainingOrderModel->planUserRel->pluck('userId')->toArray();
        $joinStaff       = array_column($collegeTrainingOrderModel->userRel->toArray(), null, 'userId');

        $staffData = (new RmsShopApi())->getShopStaffListByShopId($collegeTrainingOrderModel->studentShopId)['data']['list'] ?? [];
        //获取已经删除的用户
        $delUser = array_values(array_diff(array_merge($realityStaffIds, $expectStaffIds), array_column($staffData, 'id')));
        //已删除用户信息
        if (!empty($delUser)) {
            $userInfo = (new RmsUserApi())->getUserInfoByIds($delUser)['data'];
            foreach ($userInfo as $item) {
                $staffData[] = [
                    'id'        => $item['id'],
                    'role'      => [
                        [
                            'roleId'   => 0,
                            'roleName' => '已离职'
                        ]
                    ],
                    'username'  => $item['username'],
                    'mobile'    => $item['mobile'],
                    'status'    => '正常',
                    'statusInt' => 0,
                    'avatar'    => $item['avatar']
                ];
            };
        }
        // 用户理论考试次数
        $examNums = CollegeTrainingOrderUserModel::query()
                                                 ->withoutGlobalScope('isHistory')
                                                 ->where('trainingOrderId', $collegeTrainingOrderModel->id)
                                                 ->whereIn('examResult', [
                                                     CollegeTrainingOrderUserModel::RESULT_OK,
                                                     CollegeTrainingOrderUserModel::RESULT_FAIL
                                                 ])
                                                 ->groupBy('userId')
                                                 ->selectRaw('userId, count(*) as ct')
                                                 ->get()
                                                 ->keyBy('userId');

        $expect  = [];  //预计参与
        $reality = [];  //实际参与
        collect($staffData)->each(function ($staff) use ($realityStaffIds, $expectStaffIds, &$expect, &$reality, $joinStaff, $collegeTrainingOrderModel, $examNums) {
            $joinUser = [
                'examNo'     => $joinStaff[$staff['id']]['examNo'] ?? '',
                'examNum'    => $examNums[$staff['id']]['ct'] ?? 0,
                'examResult' => $joinStaff[$staff['id']]['examResult'] ?? 0,

                'role'             => collect($staff['role'])->implode('roleName', ','),
                'name'             => $staff['username'],
                'mobile'           => $staff['mobile'],
                'userId'           => $staff['id'],
                'isShowScore'      => ($joinStaff[$staff['id']]['examResult'] ?? 0) != 0,
                'courseScore'      => $joinStaff[$staff['id']]['examActualScore'] ?? 0,
                'practiceScore'    => $joinStaff[$staff['id']]['practiceScore'] ?? 0,
                'comment'          => $joinStaff[$staff['id']]['comment'] ?? "",
                'practiceCheckUrl' => collect(($joinStaff[$staff['id']]['resource_practice_check_urls_rel'] ?? []))->map(function ($resourcesModel) {
                    return picturePath($resourcesModel['url']);
                })->toArray(),
            ];
            if (in_array($staff['id'], $realityStaffIds)) {

                // 补考按钮
                if ($joinUser['examResult'] == CollegeTrainingOrderUserModel::RESULT_FAIL && in_array($collegeTrainingOrderModel->status,
                        [CollegeTrainingOrderModel::STATUS_ING, CollegeTrainingOrderModel::STATUS_WAIT_UPLOAD])) {
                    $joinUser['repairBtn'] = 1;
                } else {
                    $joinUser['repairBtn'] = 0;
                }

                $reality[] = $joinUser;
            }
            if (in_array($staff['id'], $expectStaffIds)) {
                $expect[] = $joinUser;
            }
        });
        //获得校区信息
        $campusInfo = CollegeCourseService::campusInfo()[CollegeTrainingPlanModel::CAMPUS_CONFIG_MAPPING[(int)optional($collegeTrainingOrderModel->planRel)->campus] ?? 0] ?? [];
        //获取日志所需用户名
        $userIds  = $collegeTrainingOrderModel->logRel->pluck('handleId')->toArray();
        $userData = RmsUserService::getRmsUserInfoByUserIds($userIds)['data'] ?? [];
        $userList = array_column($userData, 'username', 'id');

        // 确认培训订单按钮
        if (in_array($collegeTrainingOrderModel->status,
            [CollegeTrainingOrderModel::STATUS_COLLEGE_CONFIRM, CollegeTrainingOrderModel::STATUS_MERCHANT_CONFIRM])) {
            $confirmBtn = 1;
        } else {
            $confirmBtn = 0;
        }

        // 修改带训门店按钮
        if ($collegeTrainingOrderModel->teacherShopId && !in_array($collegeTrainingOrderModel->status,
                [CollegeTrainingOrderModel::STATUS_FINISH, CollegeTrainingOrderModel::STATUS_CLOSE])) {
            $editTeacherShopBtn = 1;
        } else {
            $editTeacherShopBtn = 0;
        }

        // 开业时间
        $mainProcessId = OpenShopMainProcessModel::query()->where('shopId', $collegeTrainingOrderModel->studentShopId)->orderByDesc('id')->value('id');
        $startBusinessTime = OpenShopStartBusinessModel::query()->where('mainProcessId', $mainProcessId)->value('startBusinessTime') ?? 0;
        if (!$startBusinessTime) {

            // 预计开业时间
            $startBusinessTime = OpenShopSiteLocationModel::query()->where('mainProcessId', $mainProcessId)->value('openTime') ?? 0;
        }
        $startBusinessDate = $startBusinessTime > 0 ? date('Y-m-d', $startBusinessTime) : '';


        return [
            'baseInfo' => [
                'id'               => $collegeTrainingOrderModel->id,
                'orderNo'          => $collegeTrainingOrderModel->orderNo,
                'planId'           => (int)optional($collegeTrainingOrderModel->planRel)->id,
                'planName'         => (string)optional($collegeTrainingOrderModel->planRel)->name,
                'status'           => $collegeTrainingOrderModel->status,
                'portrait'         => $collegeTrainingOrderModel->portrait,
                'statusText'       => CollegeTrainingOrderModel::STATUS_TEXT[$collegeTrainingOrderModel->status] ?? '-',
                'trainType'        => CollegeTrainingPlanModel::TYPE_MAPPING[(int)optional($collegeTrainingOrderModel->planRel)->type] ?? '-',
                'address'          => $campusInfo['address'] ?? '-',
                'contactsName'     => $campusInfo['contactName'] ?? '-',
                'contactsMobile'   => $campusInfo['contactPhone'] ?? '',
                'campus'           => $campusInfo['name'] ?? '-',
                'campusId'         => (int)optional($collegeTrainingOrderModel->planRel)->campus,
                'startTime'        => (int)optional($collegeTrainingOrderModel->planRel)->planStartTime ? formatDateYmd((int)optional($collegeTrainingOrderModel->planRel)->planStartTime) : '-',
                'endTime'          => (int)optional($collegeTrainingOrderModel->planRel)->planEndTime ? formatDateYmd((int)optional($collegeTrainingOrderModel->planRel)->planEndTime) : '-',
                'createdAt'        => $collegeTrainingOrderModel->createdAt->toDateTimeString(),
                'courseStartTime'  => (int)optional($collegeTrainingOrderModel->planRel)->courseStartTime ? formatDate((int)optional($collegeTrainingOrderModel->planRel)->courseStartTime) : '不限制',
                'practiceTraining' => collect($collegeTrainingOrderModel->resourcePracticeTrainingRel)->map(function (ResourcesModel $resourcesModel) {
                    return picturePath($resourcesModel->url);
                })->toArray(),
                'failLetter'       => collect($collegeTrainingOrderModel->resourceFailLetterRel)->map(function (ResourcesModel $resourcesModel) {
                    return picturePath($resourcesModel->url);
                })->toArray(),
                'lat'              => $campusInfo['lat'] ?? 39.916527,   //todo
                'lng'              => $campusInfo['lng'] ?? 116.397128,
                'teacherShopId'    => $collegeTrainingOrderModel->teacherShopId,
                'result'         => $collegeTrainingOrderModel->result,

                'confirmBtn' => $confirmBtn, // 确认培训订单按钮
                'editTeacherShopBtn' => $editTeacherShopBtn, // 修改带训门店按钮
            ],
            'shopInfo' => [
                'shopCode'    => $shopInfo[$collegeTrainingOrderModel->studentShopId]['shopCode'] ?? '-',
                'shopName'    => $shopInfo[$collegeTrainingOrderModel->studentShopId]['name'] ?? '-',
                'shopAddress' => $shopInfo[$collegeTrainingOrderModel->studentShopId]['address'] ?? '-',
                'shopId'      => $collegeTrainingOrderModel->studentShopId,
                'userName'    => (string)optional($collegeTrainingOrderModel->userIdentityRel)->name,
                'userMobile'  => (string)optional($collegeTrainingOrderModel->userBaseInfoRel)->mobile,
                'teacherShopCode' => (string)($shopInfo[$collegeTrainingOrderModel->teacherShopId]['shopCode'] ?? '-'),
                'teacherShopName' => (string)($shopInfo[$collegeTrainingOrderModel->teacherShopId]['name'] ?? '-'),
                'startBusinessDate' => $startBusinessDate,
            ],
            'joinUser' => [
                'expect'  => $expect,
                'reality' => $reality,
            ],
            'log'      => collect($collegeTrainingOrderModel->logRel)->map(function (CollegeTrainingOrderLogModel $collegeTrainingOrderLogModel) use ($userList) {
                return [
                    'time'     => $collegeTrainingOrderLogModel->createdAt->toDateTimeString(),
                    'userName' => $userList[$collegeTrainingOrderLogModel->handleId] ?? '系统',
                    'desc'     => $collegeTrainingOrderLogModel->content,
                ];
            })->toArray(),
            'confirm'  => $collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_COLLEGE_CONFIRM,  //是否展示确认
        ];

    }

    /**
     * 商家确认培训信息依赖条件
     * @param int $shopId
     * @param int $id
     * @return array
     * @throws GuzzleException
     */
    public static function getCampusAndStaff(int $shopId, int $id): array
    {
        $collegeTrainOrderModel = CollegeTrainingOrderModel::query()
            ->with(['planRel'])
            ->find($id);

        if (null == $collegeTrainOrderModel) {
            self::throwErr('获取培训订单失败');
        }

        $staffData = (new RmsShopApi())->getShopStaffListByShopId($shopId)['data']['list'] ?? [];

        return [
            'campus'     => collect(CollegeTrainingPlanModel::TRAINING_PLANS_CAMPUS_MAPPING)->map(function ($text, $value) {
                return [
                    'text'    => $text,
                    'value'   => $value,
                    'checked' => false
                ];
            })->values(),
            'staff'      => collect($staffData)->map(function ($staff) {
                return [
                    'text'    => ($staff['username'] ?? '-') . '-' . ($staff['mobile'] ?? '-'),
                    'value'   => (int)($staff['id'] ?? 0),
                    'avatar'  => $staff['avatar'] ? picturePath($staff['avatar']) : 'https://file.51kuafu.com/39/ec/053dd60265cc6014ee0bd8912f965cd8b84ad8b69fe1742fdc8a8abc3805.jpg',   //todo
                    'checked' => false
                ];
            }),
            'status'     => $collegeTrainOrderModel->status,
            'statusText' => CollegeTrainingOrderModel::STATUS_TEXT[$collegeTrainOrderModel->status] ?? '-',
        ];
    }


    /**
     * 通过校区获得培训计划
     * @param int $id
     * @return array
     */
    public static function getPlanByCampus(int $id): array
    {
        return CollegeTrainingPlanModel::query()
            ->where('status', CollegeTrainingPlanModel::TRAINING_PLANS_STATUS_DEFAULT)
            ->where('planStartTime', '>=', Carbon::now()->startOfWeek()->timestamp)
            ->orderBy('planStartTime')
            ->where('campus', $id)
            ->limit(5)
            ->get()
            ->map(function (CollegeTrainingPlanModel $collegeTrainingPlanModel) use ($id) {
                $campusInfo = CollegeCourseService::campusInfo()[CollegeTrainingPlanModel::CAMPUS_CONFIG_MAPPING[$id] ?? 0] ?? [];
                return [
                    'value'          => $collegeTrainingPlanModel->id,
                    'name'           => $collegeTrainingPlanModel->name,
                    'cycle'          => formatDateYmd($collegeTrainingPlanModel->planStartTime) . '至' . formatDateYmd($collegeTrainingPlanModel->planEndTime),
                    'address'        => $campusInfo['address'] ?? '-',
                    'contactsName'   => $campusInfo['contactName'] ?? '-',
                    'contactsMobile' => $campusInfo['contactPhone'] ?? '-',
                    'lat'            => $campusInfo['lat'] ?? 39.916527,   //todo
                    'lng'            => $campusInfo['lng'] ?? 116.397128,
                    'checked'        => false,
                    'startDate'      => formatDateYmd($collegeTrainingPlanModel->planStartTime),
                    'endDate'        => formatDateYmd($collegeTrainingPlanModel->planEndTime),
                ];
            })->toArray();
    }

    /**
     * 商家确认培训计划
     * @return void
     */
    public static function confirmTrainInfo(int $id, int $campusId, int $planId, array $staffIds, int $userId, int $check = 0)
    {
        // 校验健康证
        $userInfo = (new RmsUserApi())->getUserInfoByIds($staffIds, ['username', 'healthCardPhoto', 'healthCardEndDate'])['data'] ?? [];
        $errorMsg = [];
        foreach ($userInfo as $item) {
            if ($item['healthCardEndDate'] < time() || !strlen($item['healthCardPhoto'])) {
                $errorMsg[] = $item['username'];
            }
        }
        if (!empty($errorMsg)) {
            self::throwErr(implode(',', $errorMsg), 4001);
        }

        if ($check != 0) {
            return;
        }

        $collegeTrainOrderModel = CollegeTrainingOrderModel::query()->with('planRel')
            ->where('id', $id)
            ->first();

        //状态判断
        if (null == $collegeTrainOrderModel || $collegeTrainOrderModel->status != CollegeTrainingOrderModel::STATUS_MERCHANT_CONFIRM) {
            self::throwErr('状态异常');
        }

        DB::beginTransaction();
        try {
            //修改order状态
            CollegeTrainingOrderModel::query()
                ->where('id', $id)
                ->update([
                    'status'  => CollegeTrainingOrderModel::STATUS_COLLEGE_CONFIRM,
                    'planId'  => $planId,
                    'planNum' => count($staffIds),
                    'actualNum' => count($staffIds),
                ]);

            // 添加培训单关联用户表
            // 1.计划人员
            CollegeTrainingOrderPlanUserModel::init($staffIds, $id);

            // 2. 实际人员
            foreach ($staffIds as $staffId) {
                CollegeTrainingOrderUserModel::init($staffId, $id);
            }

            //添加日志
            CollegeTrainingOrderLogModel::add($id, '商家确认培训信息', $userId);

            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            Log::info('商家确认培训计划失败');
        }

        $userIds = json_decode(
            ConfigModel::query()
                ->where('module', 'college')
                ->where('name', 'collegeManager')
                ->value('value') ?? '', true
        );
        $users   = RmsUserService::getRmsUserInfoByUserIds($userIds)['data'] ?? [];
        $shop    = (new RmsShopApi())->getShopByIds([$collegeTrainOrderModel->studentShopId])['data']['shopList'][0] ?? [];

        foreach ($users as $user) {
            $feishuId = $user['feishuUserId'];
            $username = $user['username'];

            $appid = config('feishu.openShop.appID');
            $url   = "https://applink.feishu.cn/client/web_app/open?appId={$appid}&path=college/training_order/detail&mode=window&id={$collegeTrainOrderModel->id}";

            $params = [
                $collegeTrainOrderModel->orderNo,
                '审批',
                '培训单商学院待确认',
                $shop['shopCode'],
                $shop['name'],
                $username,
                $collegeTrainOrderModel->createdAt->toDateString(),
                date('Y-m-d H:i:s', ($collegeTrainOrderModel->planRel->planEndTime ?? time()) - 1),
                $url
            ];

            $templateJson = vsprintf(file_get_contents(resource_path('College/feishu/notifyTemplate/waitCollegeConfirm.json')), $params);

            dispatch((new FsMessageJob($feishuId, json_decode($templateJson, true), UserPermissionAuth::MODULE_OPEN_SHOP)));
        }

        // 商家确认培训计划后 删除 商学院待培训 标签
        (new ShopTagsService('', $collegeTrainOrderModel->studentShopId))->delSchoolTag();
    }
}
